/**
 * Copyright (C) 2009 Matteo Merli <mm@merlimat.org>
 * 
 * $Id: JavaObject.java 21 2009-01-12 17:30:19Z matteo.merli $
 * $URL: http://pxl-lang.googlecode.com/svn/trunk/src/main/old_code/JavaObject.java $
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *         http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package pxl.types;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import pxl.errors.AttributeError;
import pxl.errors.TypeError;
import pxl.types.annotations.Exported;

public class JavaObject extends PxlObject
{

    private final JavaClass javaClass;

    /** Java object instance */
    private final Object object;

    protected JavaObject( JavaClass javaClass, Object object )
    {
        this.javaClass = javaClass;
        this.object = object;
    }

    public Object getObject()
    {
        return object;
    }

    @Override
    public String getType()
    {
        return javaClass.getCompleteName();
    }

    @Exported
    @Override
    public PxlObject __new__( List<PxlObject> args )
    {
        return null;
    }

    @Exported
    @Override
    public PxlObject __getattr__( String attrName )
    {
        JavaMethod method = javaClass.getMemberMethod( attrName );

        if ( method != null )
            return new MemberMethod( this, method );

        PxlObject field = javaClass.getMemberField( attrName );

        if ( field == null )
            throw new AttributeError( this, attrName );

        return field;
    }

    @Override
    public void __setattr__( String attrName, PxlObject value )
    {
        throw new TypeError( "Cannot set an attribute on a Java Object." );
    }

    @Exported
    @Override
    public PxlList __dir__()
    {
        List<PxlString> list = new ArrayList<PxlString>();
        for ( String method : javaClass.getMemberMethodNames() )
            list.add( new PxlString( method ) );

        for ( String field : javaClass.getMemberFieldNames() )
            list.add( new PxlString( field ) );

        Collections.sort( list );
        return new PxlList( list );
    }

    @Exported
    @Override
    public PxlString __repr__()
    {
        if ( object == null )
            return new PxlString( "null" );

        StringBuilder sb = new StringBuilder();
        sb.append( '\'' );
        sb.append( object.toString() );
        sb.append( '\'' );
        return new PxlString( sb.toString() );
    }

    @Exported
    @Override
    public PxlString __str__()
    {
        if ( object == null )
            return new PxlString( "null" );

        return new PxlString( object.toString() );
    }

    // Attributes

    // / Not used
    @Override
    protected PxlObject getAttribute( String name )
    {
        return null;
    }

    @Override
    protected Collection<String> getAttributeNames()
    {
        return null;
    }

}
